package com.wayne;

import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import org.springframework.boot.jdbc.DataSourceBuilder;

import javax.sql.DataSource;
import java.io.File;
import java.io.IOException;
import java.util.Properties;
import java.util.Scanner;

public class Generator {
  /**
   * 读取控制台内容
   *
   * @param tip
   * @return
   */
  public static String scanner(String tip) {
    Scanner scanner = new Scanner(System.in);
    StringBuilder help = new StringBuilder();
    help.append(String.format("请输入%s：", tip));
    System.out.print(help.toString());
    if (scanner.hasNext()) {
      String ipt = scanner.next();
      if (StringUtils.isNotEmpty(ipt)) {
        return ipt;
      }
    }
    throw new MybatisPlusException(String.format("请输入正确的%s!", tip));
  }

  public static void main(String[] args) throws IOException {
    Properties properties = new Properties();
    properties.load(Generator.class.getResourceAsStream("/mp.generator.properties"));
    String basePath = System.getProperty("user.dir") + File.separator + properties.getProperty("code.basePath");
    String tableName = scanner("需要生成的表名");
    String daoPackage = scanner("sub dao package");
    if (StringUtils.isNotEmpty(daoPackage)) {
      daoPackage += ".";
    }
    DataSource dataSource = DataSourceBuilder
        .create()
        .driverClassName(properties.getProperty("jdbc.driver.className"))
        .password(properties.getProperty("jdbc.password"))
        .username(properties.getProperty("jdbc.username"))
        .url(properties.getProperty("jdbc.url")).build();
    DataSourceConfig.Builder dataSourceBuilder = new DataSourceConfig.Builder(dataSource);
    String finalDaoPackage = daoPackage;
    FastAutoGenerator.create(dataSourceBuilder)
        /**
         * 全局配置
         */
        .globalConfig(builder -> {
          builder.author("wayne")  // 设置作者
//              .enableSwagger()     // 开启 swagger 模式
              .dateType(DateType.TIME_PACK)  //时间策略
              .commentDate("yyyy-MM-dd")  // 注释日期
              .disableOpenDir()    // 禁止打开输出目录
              .outputDir(basePath); // 输出文件目录
        })
        /**
         * 包配置
         */
        .packageConfig(builder -> {
          // 父包名 默认 com.baomidou
          builder.parent(properties.getProperty("code.package"))
              // Controller 包名 默认controller
              .controller(finalDaoPackage + "controller")
              // Mapper 包名 默认 mapper
              .mapper(finalDaoPackage + "mapper")
              // Service 包名 默认 service
              .service(finalDaoPackage + "service")
              // Service Impl 包名 默认 service.impl
              .serviceImpl(finalDaoPackage + "service.impl")
              // Entity 包名 默认 common
              .entity(finalDaoPackage + "model")
              // Mapper XML 包名 默认 mapper.xml
              .xml(finalDaoPackage + "mapper.xml");
              // xml 的路径配置信息
//              .pathInfo(Collections.singletonMap(OutputFile.mapperXml, basePath));
        })
        /**
         * 策略配置
         */
        .strategyConfig(builder -> {
          builder.addInclude(tableName.split(",")) // 设置要生成的表名
            .addTablePrefix(properties.getProperty("code.table.prefix")) // 表前缀
            // .enableCapitalMode() // 开启大写命名	默认值:false
            // .enableSkipView() // 开启跳过视图	默认值:false
            // .disableSqlFilter() // 禁用 sql 过滤	默认值:true，语法不能支持使用 sql 过滤表的话，可以考虑关闭此开关
            // .enableSchema()    // 启用 schema	默认值:false，多 schema 场景的时候打开
            // .likeTable(LikeTable)    // 模糊表匹配(sql 过滤)	likeTable 与 notLikeTable 只能配置一项
            // .notLikeTable(LikeTable)    // 模糊表排除(sql 过滤)	likeTable 与 notLikeTable 只能配置一项
            // .addExclude()    // 增加表排除匹配(内存过滤)	include 与 exclude 只能配置一项
            // .addTableSuffix(String...)	// 增加过滤表后缀
            // .addFieldPrefix(String...)	// 增加过滤字段前缀
            // .addFieldSuffix(String...)	// 增加过滤字段后缀
            // entity 配置
            .entityBuilder()
            .enableLombok() //开启lombok
            .enableTableFieldAnnotation() // 开启生成实体时生成字段注解
            .disableSerialVersionUID()    // 禁用生成 serialVersionUID	默认值:true
            // .enableColumnConstant()    // 开启生成字段常量	默认值:false
            .enableChainModel()    // 开启链式模型	默认值:false
            .enableRemoveIsPrefix()    // 开启 Boolean 类型字段移除 is 前缀	默认值:false
            .naming(NamingStrategy.underline_to_camel)    // 数据库表映射到实体的命名策略	默认下划线转驼峰命名:NamingStrategy.underline_to_camel
            //  .logicDeleteColumnName("del_flag") // 逻辑删除字段
            // controller 配置
            .controllerBuilder()
            .formatFileName("%sController")
            .enableHyphenStyle() // 开启驼峰转连字符	默认值:false
            .enableRestStyle()   // 开启生成@RestController 控制器
            // service配置
            .serviceBuilder()
            // 设置 service 接口父类	BaseService.class
            .superServiceClass(IService.class)
            // 设置 service 实现类父类	BaseServiceImpl.class
            .superServiceImplClass(ServiceImpl.class)
            .formatServiceFileName("%sService")
            .formatServiceImplFileName("%sServiceImpl")
            // .convertServiceFileName(ConverterFileName)    // 转换 service 接口文件名称
            // .convertServiceImplFileName(ConverterFileName)    // 转换 service 实现类文件名称
            // dao 配置
            .mapperBuilder()
              .superClass(BaseMapper.class)    // 设置父类	BaseMapper.class
              .formatMapperFileName("%sMapper")
              .formatXmlFileName("%sMapper")
              .enableMapperAnnotation();
        })
        /**
         * 模板配置
         */
        .templateConfig(builder -> {
          // WARN : 使用我们自定义模板 需要注意虽然我们文件是以ftl结尾，但是这里不要加上ftl,不然会报模板引擎找不到文件
          builder
              .entity("/templates/Entity.java") // 自定义entity模板
              .controller("/templates/Controller.java") // 自定义controller模板
              .service("/templates/Service.java") // 自定义service模板
              .serviceImpl("/templates/ServiceImpl.java") // 自定义servicei.mpl模板
              .mapper("/templates/Mapper.java") // 自定义mapper模板
              .mapperXml("/templates/Mapper.xml") ; // 自定义xml模板

        })
        .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板，默认的是Velocity引擎模板
        .execute();
  }
}
